﻿using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using InfoJetSoft.Service.Entity;

namespace InfoJetSoft.Service.Util
{

    public class ExtXdFormattingFunction : IExtensionFunctions
	{

		private Form form = null;

		public ExtXdFormattingFunction( Form frm ){
			this.form = frm;
        }

        //CID 0755 //2011.01.14 //Begin
        #region IExtensionFunction Members

        public string Prefix
        {
            get { return this.form.Manifest.NsResolver.GetPrefix(this.NamespaceURI); }
        }

        public string NamespaceURI
        {
            get { return JetConstant.URI_XDFORMATTING; }
        }

        public IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] argTypes)
        {
            throw new InfoJetException("Unimplemented Function.", prefix + ":" + name);
        }

        public object InvokeFunction(string prefix, string name, XsltContext xsltContext, object[] args, XPathNavigator docContext)
        {
            throw new InfoJetException("Unimplemented Function.", prefix + ":" + name);
        }

        #endregion
        //CID 0755 //2011.01.14 //End
		
		public string formatString(System.Object data, string type, string format)
		{
			string result = innerFormatString(data, type, format);
			return result;
		}
		
		private string innerFormatString(System.Object data, string type, string format)
		{
			string nodeValue = null;
			XmlNode node = null;
			if (data is XPathNodeIterator)
			{
				XPathNodeIterator nodeIterator = (XPathNodeIterator) data;
				if (nodeIterator.MoveNext())
				{
					nodeValue = nodeIterator.Current.Value;
					node = ((IHasXmlNode)nodeIterator.Current).GetNode();
				}
				else
				{
					return "";
				}
				if (type == null || format == null)
				{
					return nodeValue;
				}
				return formatNode( this.form, node, nodeValue, type, format, false, true );
			}
			else
			{
				nodeValue = data + "";
				return formatNode( this.form, null, nodeValue, type, format, false, true );
			}
			
		}

		public static string formatNode( Form form, XmlNode node, string nodeValue, string type, string format, bool setNodeValue, bool nodeValueFormatted ){
			//CID 0500 //2010.08.04 //Begin
            string schemaType = ParsedPSVI.GetSchemaType(form, node);
            if (schemaType != null && schemaType.ToLower().Equals("string"))
            {
                //string类型无论format是什么,都不需要进行格式化.
                return nodeValue;
            }
            //CID 0500 //2010.08.04 //End
            
            //CID 0116 //2008.09.15 //Begin
			if( form.FieldErrorList != null )
			{
				foreach( FieldError fieldError in form.FieldErrorList )
				{
					//如果这个节点Schema错误,就不需要再继续格式化,应该让用户先修正Schema错误.
					if( fieldError.FieldNode.Equals( node ) && fieldError.ErrorType.Equals( FieldError.SchemaError ) )
					{
						return nodeValue;
					}
				}
			}
			//CID 0116 //2008.09.15 //End
			
			TypeFormat typeFormat = new TypeFormat(type, format);

			string formatedValue = null;
			if (nodeValue != null) {
				if (type.Equals(NumberFormat.Number)) {
					formatedValue = NumberFormater.format(form, node, nodeValue, typeFormat, setNodeValue, nodeValueFormatted);
				}
				else if (type.Equals(NumberFormat.Double)) {
					formatedValue = NumberFormater.format(form, node, nodeValue, typeFormat, setNodeValue, nodeValueFormatted);
				}
				else if (type.Equals(NumberFormat.Percentage)) {
					formatedValue = NumberFormater.format(form, node, nodeValue, typeFormat, setNodeValue, nodeValueFormatted);
				}
				else if (type.Equals(NumberFormat.Currency)) {
					formatedValue = NumberFormater.format(form, node, nodeValue, typeFormat, setNodeValue, nodeValueFormatted);
				}
				else if (type.Equals("date")) {
					formatedValue = DateFormater.format(form, node, nodeValue, typeFormat, setNodeValue);
				}
				else if (type.Equals("time")) {
					formatedValue = TimeFormater.format(form, node, nodeValue, typeFormat, setNodeValue);
				}
				else if (type.Equals("datetime")) {
					formatedValue = DateTimeFormater.format(form, node, nodeValue, typeFormat, setNodeValue);
				}
				else {
					formatedValue = nodeValue;
				}
			}
			else {
				formatedValue = nodeValue;
			}
			return formatedValue;
		}
    }
}